package com.hubu.mapper.impl;

import com.hubu.mapper.KnowledgeGraphDao;
import com.hubu.mapper.KGGraphDao;
import com.hubu.model.ArticulationProduct;
import com.hubu.model.NodeItem;
import com.hubu.request.GraphQuery;
import com.hubu.request.NodeCoordinateItem;
import com.hubu.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import javax.xml.soap.Node;
import java.lang.reflect.Array;
import java.text.DecimalFormat;
import java.util.*;


/**
 * @Author xiedi
 * @Date: 2022/11/5
 */
@Repository
public class KGGraphRepository implements KGGraphDao {
    @Autowired
    private KnowledgeGraphDao knowledgeGraphDao;

    /**
     * 领域标签分页
     */
    @Override
    public GraphPageRecord<HashMap<String, Object>> getPageDomain(GraphQuery queryItem) {
        GraphPageRecord<HashMap<String, Object>> resultRecord = new GraphPageRecord<HashMap<String, Object>>();
        try {
            String totalCountQuery = "MATCH (n) RETURN count(distinct labels(n)) as count";
            long totalCount = 0;
            totalCount = Neo4jUtil.getGraphValue(totalCountQuery);
            if (totalCount > 0) {
                int skipCount = (queryItem.getPageIndex() - 1) * queryItem.getPageSize();
                int limitCount = queryItem.getPageSize();
                String domainSql = String.format(
                        "START n=node(*)  RETURN distinct labels(n) as domain,count(n) as nodeCount order by nodeCount desc SKIP %s LIMIT %s",
                        skipCount, limitCount);
                List<HashMap<String, Object>> pageList = Neo4jUtil.getGraphNode(domainSql);
                resultRecord.setPageIndex(queryItem.getPageIndex());
                resultRecord.setPageSize(queryItem.getPageSize());
                resultRecord.setTotalCount(totalCount);
                resultRecord.setNodeList(pageList);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return resultRecord;
    }

    /**
     * 删除Neo4j 标签
     */
    @Override
    public void deleteKgDomain(String domain) {
        try {
            String deleteRelation = String.format("MATCH (n:`%s`)-[r]-(m) detach delete r", domain);
            Neo4jUtil.runCypherSql(deleteRelation);
            String deleteNode = String.format("MATCH (n:`%s`) detach delete n", domain);
            Neo4jUtil.runCypherSql(deleteNode);
        } catch (Exception e) {
            e.printStackTrace();

        }
    }

    /**
     * 查询图谱节点和关系
     */
    @Override
    public HashMap<String, Object> getDomainGraph(GraphQuery query) {

        HashMap<String, Object> nr = new HashMap<String, Object>();
        try {
            String domain = query.getDomain();
            // MATCH (n:`症状`) -[r]-(m:症状) where r.name='治疗' or r.name='危险因素' return n,m
            if (!StringUtil.isBlank(domain)) {
                String cqr = "";
                List<String> lis = new ArrayList<String>();
                //关系名称
                if (query.getRelation() != null && query.getRelation().length > 0) {
                    for (String r : query.getRelation()) {
                        String it = String.format("r.name='%s'", r);
                        lis.add(it);
                    }
                    cqr = String.join(" or ", lis);
                }
                String cqWhere = "";
                //节点名称
                if (!StringUtil.isBlank(query.getNodeName()) || !StringUtil.isBlank(cqr)) {
                    if (!StringUtil.isBlank(query.getNodeName())) {
                        String nodeIdCql = String.format("match(m:`%s`) where m.name='%s' return distinct(m)", domain, query.getNodeName());
                        Integer nodeId = Neo4jUtil.getNodeId(nodeIdCql);
                        if (query.getMatchType() == 0) {
                            cqWhere = String.format("where n.name ='%s' and id(n) =%s", query.getNodeName(), nodeId);
                        } else {
                            cqWhere = String.format("where n.name contains('%s') and id(n) =%s", query.getNodeName(), nodeId);
                        }
                    }
                    String nodeOnly = cqWhere;
                    if (!StringUtil.isBlank(cqr)) {
                        if (StringUtil.isBlank(cqWhere)) {
                            cqWhere = String.format(" where ( %s )", cqr);
                        } else {
                            cqWhere += String.format(" and ( %s )", cqr);
                        }

                    }
                    String nodeSql = String.format("MATCH (n:`%s`)<-[r]-> (m) %s RETURN distinct(n) limit %s", domain,
                            cqWhere, query.getPageSize());
                    List<HashMap<String, Object>> graphSourceNode = Neo4jUtil.getGraphNode(nodeSql);

                    String nodeSql2 = String.format("MATCH (n:`%s`)<-[r]-> (m) %s RETURN distinct(m) limit %s", domain,
                            cqWhere, query.getPageSize());
                    List<HashMap<String, Object>> graphTargetNode = Neo4jUtil.getGraphNode(nodeSql2);

                    graphSourceNode.addAll(graphTargetNode);
                    nr.put("node", graphSourceNode);

                    String domainSql = String.format("MATCH (n:`%s`)<-[r]-> (m) %s RETURN distinct(r) limit %s", domain,
                            cqWhere, query.getPageSize());// m是否加领域
                    List<HashMap<String, Object>> graphRelation = Neo4jUtil.getGraphRelationShip(domainSql);
                    nr.put("relationship", graphRelation);
                    /*// 下边的查询查不到单个没有关系的节点,考虑要不要左箭头
                    String nodeSql = String.format("MATCH (n:`%s`) <-[r]->(m) %s return n,r,m limit %s", domain, cqWhere,
                            query.getPageSize());
                    HashMap<String, Object> graphNode = Neo4jUtil.getGraphNodeAndShip(nodeSql);

                    Object node = graphNode.get("node");
                    // 没有关系显示则显示节点
                    if (node != null) {
                        nr.put("node", graphNode.get("node"));
                        nr.put("relationship", graphNode.get("relationship"));
                    } else {
                        String nodecql = String.format("MATCH (n:`%s`) %s RETURN distinct(n) limit %s", domain,
                                nodeOnly, query.getPageSize());
                        List<HashMap<String, Object>> nodeItem = Neo4jUtil.getGraphNode(nodecql);
                        nr.put("node", nodeItem);
                        nr.put("relationship", new ArrayList<HashMap<String, Object>>());
                    }*/
                } else {
                    String nodeSql = String.format("MATCH (n:`%s`)<-[r]-> (m) %s RETURN distinct(n) limit %s", domain,
                            cqWhere, query.getPageSize());
                    List<HashMap<String, Object>> graphSourceNode = Neo4jUtil.getGraphNode(nodeSql);
                    for (HashMap<String, Object> map : graphSourceNode) {
                        map.put("label",query.getDomain());
                    }

                    String nodeSql2 = String.format("MATCH (n:`%s`)<-[r]-> (m) %s RETURN distinct(m) limit %s", domain,
                            cqWhere, query.getPageSize());
                    List<HashMap<String, Object>> graphTargetNode = Neo4jUtil.getGraphNode(nodeSql2);
                    for (HashMap<String, Object> map : graphTargetNode) {
                        map.put("label", query.getDomain());
                    }
                    graphSourceNode.addAll(graphTargetNode);
                    nr.put("node", graphSourceNode);

                    String domainSql = String.format("MATCH (n:`%s`)<-[r]-> (m) %s RETURN distinct(r) limit %s", domain,
                            cqWhere, query.getPageSize());// m是否加领域
                    List<HashMap<String, Object>> graphRelation = Neo4jUtil.getGraphRelationShip(domainSql);
                    nr.put("relationship", graphRelation);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return nr;
    }

    /**
     * 获取节点列表
     */
    @Override
    public HashMap<String, Object> getDomainNodes(String domain, Integer pageIndex, Integer pageSize) {
        HashMap<String, Object> resultItem = new HashMap<String, Object>();
        List<HashMap<String, Object>> ents = new ArrayList<HashMap<String, Object>>();
        List<HashMap<String, Object>> concepts = new ArrayList<HashMap<String, Object>>();
        List<HashMap<String, Object>> props = new ArrayList<HashMap<String, Object>>();
        List<HashMap<String, Object>> methods = new ArrayList<HashMap<String, Object>>();
        List<HashMap<String, Object>> entitys = new ArrayList<HashMap<String, Object>>();
        try {
            int skipCount = (pageIndex - 1) * pageSize;
            int limitCount = pageSize;
            String domainSql = String.format("START n=node(*) MATCH (n:`%s`) RETURN n SKIP %s LIMIT %s", domain,
                    skipCount, limitCount);
            if (!StringUtil.isBlank(domain)) {
                ents = Neo4jUtil.getGraphNode(domainSql);
                for (HashMap<String, Object> hashMap : ents) {
                    Object et = hashMap.get("entityType");
                    if (et != null) {
                        String typeStr = et.toString();
                        if (StringUtil.isNotBlank(typeStr)) {
                            int type = Integer.parseInt(et.toString());
                            if (type == 0) {
                                concepts.add(hashMap);
                            } else if (type == 1) {
                                entitys.add(hashMap);
                            } else if (type == 2 || type == 3) {
                                props.add(hashMap);// 属性和方法放在一起展示
                            } else {
                                // methods.add(hashMap);
                            }
                        }
                    }
                }
                resultItem.put("concepts", concepts);
                resultItem.put("props", props);
                resultItem.put("methods", methods);
                resultItem.put("entitys", entitys);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return resultItem;
    }

    /**
     * 获取某个领域指定节点拥有的上下级的节点数
     */
    @Override
    public long getRelationNodeCount(String domain, long nodeId) {
        long totalCount = 0;
        try {
            if (!StringUtil.isBlank(domain)) {
                String nodeSql = String.format("MATCH (n:`%s`) <-[r]->(m)  where id(n)=%s return count(m)", domain,
                        nodeId);
                totalCount = Neo4jUtil.getGraphValue(nodeSql);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return totalCount;
    }

    /**
     * 创建领域,默认创建一个新的节点,给节点附上默认属性
     */
    @Override
    public void createDomain(String domain) {
        try {
            String cypherSql = String.format(
                    "create (n:`%s`{entityType:0,name:''}) return id(n)", domain);
            Neo4jUtil.runCypherSql(cypherSql);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
    public void quickCreateDomain(String domain,String nodeName) {
        try {
            String cypherSql = String.format(
                    "create (n:`%s`{entityType:0,name:'%s'}) return id(n)", domain,nodeName);
            Neo4jUtil.runCypherSql(cypherSql);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 获取/展开更多节点,找到和该节点有关系的节点
     */
    @Override
    public HashMap<String, Object> getMoreRelationNode(String domain, String nodeId, Integer round) {
        HashMap<String, Object> results = new HashMap<String, Object>();
        //封装总的节点和关系
        ArrayList<HashMap<String,Object>> nodeList = new ArrayList<>();
        ArrayList<HashMap<String,Object>> relList = new ArrayList<>();
        //所要遍历的nodeId
        ArrayList<String> nodeIdList = new ArrayList<>();
        HashMap<String, Object> result = getDeepNodeAndRel(domain, nodeId);
        List<HashMap<String, Object>> node = (List<HashMap<String, Object>>) result.get("node");
        for (HashMap<String, Object> map : node) {
            nodeList.add(map);
            nodeIdList.add((String) map.get("uuid"));
        }
        List<HashMap<String, Object>> relationship = (List<HashMap<String, Object>>) result.get("relationship");
        for (HashMap<String, Object> map : relationship) {
            relList.add(map);
        }
        if (round == 2){
            //ArrayList<String> nodeIds = new ArrayList<>();
            for (String id : nodeIdList) {
                HashMap<String, Object> nodeAndRel = getDeepNodeAndRel(domain, id);
                List<HashMap<String, Object>> n = (List<HashMap<String, Object>>) nodeAndRel.get("node");
                for (HashMap<String, Object> map : n) {
                    nodeList.add(map);
                    //nodeIds.add((String) map.get("uuid"));
                }
                List<HashMap<String, Object>> r = (List<HashMap<String, Object>>) nodeAndRel.get("relationship");
                for (HashMap<String, Object> map : r) {
                    relList.add(map);
                }
            }
        }else if (round == 3){
            //round为2的nodeIds
            ArrayList<String> nodeIds = new ArrayList<>();
            //二层nodeId遍历
            for (String id : nodeIdList) {
                HashMap<String, Object> nodeAndRel = getDeepNodeAndRel(domain, id);
                List<HashMap<String, Object>> n = (List<HashMap<String, Object>>) nodeAndRel.get("node");
                for (HashMap<String, Object> map : n) {
                    nodeList.add(map);
                    nodeIds.add((String) map.get("uuid"));
                }
                List<HashMap<String, Object>> r = (List<HashMap<String, Object>>) nodeAndRel.get("relationship");
                for (HashMap<String, Object> map : r) {
                    relList.add(map);
                }
            }
            //三层nodeId遍历
            for (String id : nodeIds) {
                HashMap<String, Object> nodeAndRel = getDeepNodeAndRel(domain, id);
                List<HashMap<String, Object>> n = (List<HashMap<String, Object>>) nodeAndRel.get("node");
                for (HashMap<String, Object> map : n) {
                    nodeList.add(map);
                    //nodeIds.add((String) map.get("uuid"));
                }
                List<HashMap<String, Object>> r = (List<HashMap<String, Object>>) nodeAndRel.get("relationship");
                for (HashMap<String, Object> map : r) {
                    relList.add(map);
                }
            }
        }
        ArrayList<HashMap<String, Object>> newNode = new ArrayList<>();
        ArrayList<HashMap<String, Object>> newRelList = new ArrayList<>();
        //node与relationship去重
        for (HashMap<String, Object> map : nodeList) {
            if (!newNode.contains(map)){
                newNode.add(map);
            }
        }
        for (HashMap<String, Object> map : relList) {
            if (!newRelList.contains(map)){
                newRelList.add(map);
            }
        }
        results.put("node",newNode);
        results.put("relationship",newRelList);
        return results;
    }

    public HashMap<String, Object> getDeepNodeAndRel(String domain, String nodeId){
        HashMap<String, Object> map = new HashMap<>();
        //封装总的节点和关系
        ArrayList<HashMap<String,Object>> nodeList = new ArrayList<>();
        ArrayList<HashMap<String,Object>> relList = new ArrayList<>();
        String cypherSql = String.format("MATCH (n:`%s`) -[r]-(m) where id(n)=%s  return *", domain,
                nodeId);
        HashMap<String, Object> result = Neo4jUtil.getGraphNodeAndShip(cypherSql);
        //添加node数据
        List<HashMap<String,Object>> queryNodeList = (List<HashMap<String, Object>>) result.get("node");

        for (HashMap<String, Object> newNode : queryNodeList) {
            nodeList.add(newNode);
        }
        //添加relationship数据
        List<HashMap<String,Object>> queryRelList = (List<HashMap<String, Object>>) result.get("relationship");
        for (HashMap<String, Object> newRel : queryRelList) {
            relList.add(newRel);
        }
        map.put("node", nodeList);
        map.put("relationship",relList);
        return map;
    }

    /**
     * 更新节点名称
     */
    @Override
    public HashMap<String, Object> updateNodeName(String domain, String nodeId, String nodeName) {
        HashMap<String, Object> result = new HashMap<String, Object>();
        List<HashMap<String, Object>> graphNodeList = new ArrayList<HashMap<String, Object>>();
        try {
            String cypherSql = String.format("MATCH (n:`%s`) where id(n)=%s set n.name='%s' return n", domain, nodeId,
                    nodeName);
            graphNodeList = Neo4jUtil.getGraphNode(cypherSql);
            if (graphNodeList.size() > 0) {
                return graphNodeList.get(0);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 创建单个节点
     */
    @Override
    public HashMap<String, Object> createNode(String domain, NodeItem entity) {
        HashMap<String, Object> rss = new HashMap<String, Object>();
        List<HashMap<String, Object>> graphNodeList = new ArrayList<HashMap<String, Object>>();
        try {
            if (entity.getUuid() != 0) {
                String sqlKeyVal = Neo4jUtil.getKeyValCyphersql(entity);
                String cypherSql = String.format("match (n:`%s`) where id(n)=%s set %s return n", domain,
                        entity.getUuid(), sqlKeyVal);
                graphNodeList = Neo4jUtil.getGraphNode(cypherSql);
            } else {
                String propertiesString = Neo4jUtil.getFilterPropertiesJson(JsonHelper.toJSONString(entity));
                String cypherSql = String.format("create (n:`%s` %s) return n", domain, propertiesString);
                graphNodeList = Neo4jUtil.getGraphNode(cypherSql);
            }
            if (graphNodeList.size() > 0) {
                rss = graphNodeList.get(0);
                return rss;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return rss;
    }

    /**
     * 自定义uuid,重复则返回节点，不存在则创建
     * @param domain
     * @param entity
     * @return
     */
    @Override
    public HashMap<String, Object> createNodeWithUUid(String domain, NodeItem entity) {
        HashMap<String, Object> rss = new HashMap<String, Object>();
        List<HashMap<String, Object>> graphNodeList = new ArrayList<HashMap<String, Object>>();
        try {
            if (entity.getUuid() != 0) {
                String sqlKeyVal = Neo4jUtil.getKeyValCyphersql(entity);
                String cypherSql = String.format("match (n:`%s`) where id(n)=%s set %s return n", domain,
                        entity.getUuid(), sqlKeyVal);
                graphNodeList = Neo4jUtil.getGraphNode(cypherSql);
            }
            if (graphNodeList.size() > 0) {
                rss = graphNodeList.get(0);
                return rss;
            }
            entity.setName(entity.getName());
            entity.setColor(entity.getColor());
            entity.setR(30);// 默认半径
            entity.setUuid(entity.getUuid());
            String propertiesString = Neo4jUtil.getFilterPropertiesJson(JsonHelper.toJSONString(entity));
            String cypherSql = String.format("create (n:`%s` %s) return n", domain, propertiesString);
            graphNodeList = Neo4jUtil.getGraphNode(cypherSql);
            if (graphNodeList.size() > 0) {
                rss = graphNodeList.get(0);
                return rss;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return rss;
    }

    /**
     * 批量创建节点和关系
     */
    @Override
    public HashMap<String, Object> batchCreateNode(String domain, String sourceName, String sourceId, String relation,
                                                   String[] targetNames) {
        HashMap<String, Object> rss = new HashMap<String, Object>();
        List<HashMap<String, Object>> nodes = new ArrayList<HashMap<String, Object>>();
        List<HashMap<String, Object>> ships = new ArrayList<HashMap<String, Object>>();
        try {
            String cypherSqlFmt = "create (n:`%s` {name:'%s'}) return n";
            String cypherSql = String.format(cypherSqlFmt, domain, sourceName);// 概念实体
            List<HashMap<String, Object>> graphNodeList = Neo4jUtil.getGraphNode(cypherSql);
            if (graphNodeList.size() > 0) {
                HashMap<String, Object> sourceNode = graphNodeList.get(0);
                nodes.add(sourceNode);
                String sourceUuid = String.valueOf(sourceNode.get("uuid"));
                for (String tn : targetNames) {
                    String targetNodeSql = String.format(cypherSqlFmt, domain, tn);
                    List<HashMap<String, Object>> targetNodeList = Neo4jUtil.getGraphNode(targetNodeSql);
                    if (targetNodeList.size() > 0) {
                        HashMap<String, Object> targetNode = targetNodeList.get(0);
                        nodes.add(targetNode);
                        String targetUuid = String.valueOf(targetNode.get("uuid"));
                        String rSql = String.format(
                                "match(n:`%s`),(m:`%s`) where id(n)=%s and id(m)=%s create (n)-[r:RE {name:'%s'}]->(m) return r",
                                domain, domain, sourceUuid, targetUuid, relation);
                        List<HashMap<String, Object>> rShipList = Neo4jUtil.getGraphRelationShip(rSql);
                        ships.addAll(rShipList);
                    }

                }
            }
            rss.put("node", nodes);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return rss;
    }

    /**
     * 批量创建下级节点
     *
     * @param domain      领域
     * @param sourceId    源节点id
     * @param entityType  节点类型
     * @param targetNames 目标节点名称数组
     * @param relation    关系
     */
    @Override
    public HashMap<String, Object> batchCreateChildNode(String domain, String sourceId, Integer entityType,
                                                        String[] targetNames, String relation) {
        HashMap<String, Object> rss = new HashMap<String, Object>();
        List<HashMap<String, Object>> nodes = new ArrayList<HashMap<String, Object>>();
        List<HashMap<String, Object>> ships = new ArrayList<HashMap<String, Object>>();
        try {
            String cypherSqlFmt = "create (n:`%s`{name:'%s',color:'#ff4500',r:30}) return n";
            String cypherSql = String.format("match (n:`%s`) where id(n)=%s return n", domain, sourceId);
            List<HashMap<String, Object>> sourceNodeList = Neo4jUtil.getGraphNode(cypherSql);
            if (sourceNodeList.size() > 0) {
                nodes.addAll(sourceNodeList);
                for (String tn : targetNames) {
                    String targetNodeSql = String.format(cypherSqlFmt, domain, tn);
                    List<HashMap<String, Object>> targetNodeList = Neo4jUtil.getGraphNode(targetNodeSql);
                    if (targetNodeList.size() > 0) {
                        HashMap<String, Object> targetNode = targetNodeList.get(0);
                        nodes.add(targetNode);
                        String targetUuid = String.valueOf(targetNode.get("uuid"));
                        // 创建关系
                        String rSql = String.format(
                                "match(n:`%s`),(m:`%s`) where id(n)=%s and id(m)=%s create (n)-[r:RE {name:'%s'}]->(m) return r",
                                domain, domain, sourceId, targetUuid, relation);
                        List<HashMap<String, Object>> shipList = Neo4jUtil.getGraphRelationShip(rSql);
                        ships.addAll(shipList);
                    }
                }
            }
            rss.put("nodes", nodes);
            rss.put("ships", ships);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return rss;
    }

    /**
     * 批量创建同级节点
     *
     * @param domain      领域
     * @param entityType  节点类型
     * @param sourceNames 节点名称
     */
    @Override
    public List<HashMap<String, Object>> batchCreateSameNode(String domain, Integer entityType, String[] sourceNames) {
        List<HashMap<String, Object>> rss = new ArrayList<HashMap<String, Object>>();
        try {
            String cypherSqlFmt = "create (n:`%s`{name:'%s',color:'#ff4500',r:30}) return n";
            for (String tn : sourceNames) {
                String sourceNodeSql = String.format(cypherSqlFmt, domain, tn, entityType);
                List<HashMap<String, Object>> targetNodeList = Neo4jUtil.getGraphNode(sourceNodeSql);
                rss.addAll(targetNodeList);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return rss;
    }

    /**
     * 添加关系
     *
     * @param domain   领域
     * @param sourceId 源节点id
     * @param targetId 目标节点id
     * @param ship     关系
     */
    @Override
    public HashMap<String, Object> createLink(String domain, String targetDomain, long sourceId, long targetId, String ship) {
        HashMap<String, Object> rss = new HashMap<String, Object>();
        try {
            String cypherSql = String.format("MATCH (n:`%s`),(m:`%s`) WHERE id(n)=%s AND id(m) = %s "
                    + "CREATE (n)-[r:RE{name:'%s'}]->(m)" + "RETURN r", domain, targetDomain, sourceId, targetId, ship);
            List<HashMap<String, Object>> cypherResult = Neo4jUtil.getGraphRelationShip(cypherSql);
            if (cypherResult.size() > 0) {
                rss = cypherResult.get(0);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return rss;
    }

    @Override
    public HashMap<String, Object> createLinkByUuid(String domain, long sourceId, long targetId, String ship) {
        HashMap<String, Object> rss = new HashMap<String, Object>();
        try {
            String cypherSql = String.format("MATCH (n:`%s`),(m:`%s`) WHERE n.uuid=%s AND m.uuid = %s "
                    + "CREATE (n)-[r:RE{name:'%s'}]->(m)" + "RETURN r", domain, domain, sourceId, targetId, ship);
            List<HashMap<String, Object>> cypherResult = Neo4jUtil.getGraphRelationShip(cypherSql);
            if (cypherResult.size() > 0) {
                rss = cypherResult.get(0);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return rss;
    }
    /**
     * 更新关系
     *
     * @param domain   领域
     * @param shipId   关系id
     * @param shipName 关系名称
     */
    @Override
    public HashMap<String, Object> updateLink(String domain, long shipId, String shipName) {
        HashMap<String, Object> rss = new HashMap<String, Object>();
        try {
            String cypherSql = String.format("MATCH (n:`%s`) -[r]->(m) where id(r)=%s set r.name='%s' return r", domain,
                    shipId, shipName);
            List<HashMap<String, Object>> cypherResult = Neo4jUtil.getGraphRelationShip(cypherSql);
            if (cypherResult.size() > 0) {
                rss = cypherResult.get(0);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return rss;
    }

    /**
     * 删除节点(先删除关系再删除节点)
     *
     */
    @Override
    public HashMap deleteNode(String domain, long nodeId) {

        HashMap<String, Object> result = new HashMap<>();
        try {
            String rSql = String.format("MATCH (n:`%s`) -[r]-(m) where id(n)=%s return r", domain, nodeId);
            List<HashMap<String, Object>> relationShip = Neo4jUtil.getGraphRelationShip(rSql);
            String nSql = String.format("MATCH (n:`%s`)  where id(n)=%s return n", domain, nodeId);
            List<HashMap<String, Object>> graphNode = Neo4jUtil.getGraphNode(nSql);
            String deleteRelationSql = String.format("MATCH (n:`%s`) -[r]-(m) where id(n)=%s detach delete r", domain, nodeId);
            Neo4jUtil.runCypherSql(deleteRelationSql);
            String deleteNodeSql = String.format("MATCH (n:`%s`) where id(n)=%s detach delete n", domain, nodeId);
            Neo4jUtil.runCypherSql(deleteNodeSql);
            result.put("relationship",relationShip);
            result.put("graphNode",graphNode);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 删除关系
     *
     */
    @Override
    public void deleteLink(String domain, long shipId) {
        try {
            String cypherSql = String.format("MATCH (n:`%s`) -[r]-(m) where id(r)=%s detach delete r", domain, shipId);
            Neo4jUtil.runCypherSql(cypherSql);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 段落识别出的三元组生成图谱
     *
     * @param domain 领域名称
     * @param entityType 实体类型
     * @param operateType 操作类型
     * @param sourceId 节点id
     * @param rss         关系三元组
     *                    [[startname;ship;endname],[startname1;ship1;endname1],[startname2;ship2;endname2]]
     * @return node relationship
     */
    @Override
    public HashMap<String, Object> createGraphByText(String domain, Integer entityType, Integer operateType,
                                                     Integer sourceId, String[] rss) {
        HashMap<String, Object> rsList = new HashMap<String, Object>();
        try {
            List<Object> nodeIds = new ArrayList<Object>();
            List<HashMap<String, Object>> nodeList = new ArrayList<HashMap<String, Object>>();
            List<HashMap<String, Object>> shipList = new ArrayList<HashMap<String, Object>>();

            if (rss != null && rss.length > 0) {
                for (String item : rss) {
                    String[] ns = item.split(";");
                    String nodeStart = ns[0];
                    String ship = ns[1];
                    String nodeEnd = ns[2];
                    String nodeStartSql = String.format("MERGE (n:`%s`{name:'%s',entityType:'%s'})  return n", domain,
                            nodeStart, entityType);
                    String nodeEndSql = String.format("MERGE (n:`%s`{name:'%s',entityType:'%s'})  return n", domain,
                            nodeEnd, entityType);
                    // 创建初始节点
                    List<HashMap<String, Object>> startNode = Neo4jUtil.getGraphNode(nodeStartSql);
                    // 创建结束节点
                    List<HashMap<String, Object>> endNode = Neo4jUtil.getGraphNode(nodeEndSql);
                    Object startId = startNode.get(0).get("uuid");
                    if (!nodeIds.contains(startId)) {
                        nodeIds.add(startId);
                        nodeList.addAll(startNode);
                    }
                    Object endId = endNode.get(0).get("uuid");
                    if (!nodeIds.contains(endId)) {
                        nodeIds.add(endId);
                        nodeList.addAll(endNode);
                    }
                    if (sourceId != null && sourceId > 0 && operateType == 2) {// 添加下级
                        String shipSql = String.format(
                                "MATCH (n:`%s`),(m:`%s`) WHERE id(n)=%s AND id(m) = %s "
                                        + "CREATE (n)-[r:RE{name:'%s'}]->(m)" + "RETURN r",
                                domain, domain, sourceId, startId, "");
                        List<HashMap<String, Object>> shipResult = Neo4jUtil.getGraphRelationShip(shipSql);
                        shipList.add(shipResult.get(0));
                    }
                    String shipSql = String.format("MATCH (n:`%s`),(m:`%s`) WHERE id(n)=%s AND id(m) = %s "
                            + "CREATE (n)-[r:RE{name:'%s'}]->(m)" + "RETURN r", domain, domain, startId, endId, ship);
                    List<HashMap<String, Object>> shipResult = Neo4jUtil.getGraphRelationShip(shipSql);
                    shipList.addAll(shipResult);

                }
                rsList.put("node", nodeList);
                rsList.put("relationship", shipList);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return rsList;
    }

    @Override
    public void batchCreateGraph(String domain, List<Map<String, Object>> params) {
        try {
            if (params != null && params.size() > 0) {
                String nodeStr = Neo4jUtil.getFilterPropertiesJson(JsonHelper.toJSONString(params));
                String nodeCypher = String
                        .format("UNWIND %s as row " + " MERGE (n:`%s` {name:row.SourceNode,source:row.Source})"
                                + " MERGE (m:`%s` {name:row.TargetNode,source:row.Source})", nodeStr, domain, domain);
                Neo4jUtil.runCypherSql(nodeCypher);
                String relationShipCypher = String.format("UNWIND %s as row " + " MATCH (n:`%s` {name:row.SourceNode})"
                                + " MATCH (m:`%s` {name:row.TargetNode})" + " MERGE (n)-[:RE{name:row.RelationShip}]->(m)",
                        nodeStr, domain, domain);
                Neo4jUtil.runCypherSql(relationShipCypher);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
    public void batchUpdateGraphNodesCoordinate(String domain,List<NodeCoordinateItem> params) {
        try {
            if (params != null && params.size() > 0) {
                String nodeStr = Neo4jUtil.getFilterPropertiesJson(JsonHelper.toJSONString(params));
                String nodeCypher = String
                        .format("UNWIND %s as row " + " MATCH (n:`%s`)  where id(n)=row.uuid SET n.fx=row.fx,n.fy=row.fy", nodeStr, domain);
                Neo4jUtil.runCypherSql(nodeCypher);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 批量导入csv
     *
     */
    @Override
    public void batchInsertByCsv(String domain, String csvUrl, int isCreateIndex) {
        String loadNodeCypher1 = null;
        String loadNodeCypher2 = null;
        String addIndexCypher = null;



        addIndexCypher = " CREATE INDEX ON :`" + domain + "`(name);";
        loadNodeCypher1 = " USING PERIODIC COMMIT 500 LOAD CSV FROM '" + csvUrl + "' AS line " + " MERGE (:`" + domain
                + "` {name:line[0]});";
        loadNodeCypher2 = " USING PERIODIC COMMIT 500 LOAD CSV FROM '" + csvUrl + "' AS line " + " MERGE (:`" + domain
                + "` {name:line[1]});";
        // 拼接生产关系导入cypher
        String loadRelCypher = null;
        String type = "RE";
        loadRelCypher = " USING PERIODIC COMMIT 500 LOAD CSV FROM  '" + csvUrl + "' AS line " + " MATCH (m:`" + domain
                + "`),(n:`" + domain + "`) WHERE m.name=line[0] AND n.name=line[1] " + " MERGE (m)-[r:" + type + "]->(n) "
                + "	SET r.name=line[2];";
        if(isCreateIndex==0){//已经创建索引的不能重新创建
            Neo4jUtil.runCypherSql(addIndexCypher);
        }
        Neo4jUtil.runCypherSql(loadNodeCypher1);
        Neo4jUtil.runCypherSql(loadNodeCypher2);
        Neo4jUtil.runCypherSql(loadRelCypher);

    }

    @Override
    public void updateNodeFileStatus(String domain, long nodeId, int status) {
        try {
            String nodeCypher = String.format("match (n:`%s`) where id(n)=%s set n.hasFile=%s ", domain, nodeId, status);
            Neo4jUtil.runCypherSql(nodeCypher);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
    public void updateNodeImg(String domain, long nodeId, String img) {
        try {
            String nodeCypher = String.format("match (n:`%s`) where id(n)=%s set n.image='%s' ", domain, nodeId, img);
            Neo4jUtil.runCypherSql(nodeCypher);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
    public void removeNodeImg(String domain, long nodeId) {
        try {
            String nodeCypher = String.format("match (n:`%s`) where id(n)=%s remove n.image ", domain, nodeId);
            Neo4jUtil.runCypherSql(nodeCypher);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
    public void updateCoordinateOfNode(String domain, String uuid, Double fx, Double fy) {
        String cypher = null;
        if (fx == null && fy == null) {
            cypher = " MATCH (n:`" + domain + "`) where ID(n)=" + uuid
                    + " set n.fx=null, n.fy=null; ";
        } else {
            assert fx != null;
            if ("0.0".equals(fx.toString()) && "0.0".equals(fy.toString())) {
                cypher = " MATCH (n:`" + domain + "`) where ID(n)=" + uuid
                        + " set n.fx=null, n.fy=null; ";
            } else {
                cypher = " MATCH (n:`" + domain + "`) where ID(n)=" + uuid
                        + " set n.fx='" + fx + "', n.fy='" + fy + "';";
            }
        }
        Neo4jUtil.runCypherSql(cypher);
    }

    @Override
    public HashMap<String, Object> getNodes(NodeItem nodeItem) {
        HashMap<String, Object> nodeAndNum = new HashMap<>();
        Integer start = ((nodeItem.getPage() - 1) * nodeItem.getPageSize());
        String nodeSql = String.format("MATCH (n:`%s`) RETURN n skip %s limit %s", nodeItem.getDomain(),
                start, nodeItem.getPageSize());
        List<HashMap<String, Object>> graphNode = Neo4jUtil.getGraphNode(nodeSql);

        String count = String.format("MATCH (n:`%s`) return count(n)", nodeItem.getDomain());
        long totalCount = Neo4jUtil.getGraphValue(count);
        nodeAndNum.put("node",graphNode);
        nodeAndNum.put("totalCount",totalCount);
        return nodeAndNum;
    }

    @Override
    public HashMap<String, Object> getEntityLinks(NodeItem nodeItem) {
        //保存已经查询之后的节点
        List<HashMap<String, Object>> list = new ArrayList<>();

        //返回渲染的节点与关系
        ArrayList<Object> totalNode = new ArrayList<>();
        ArrayList<Object> totalShip = new ArrayList<>();
        HashMap<String, Object> map = new HashMap<>();
        Integer num = 1;
        boolean flag = getDeepEntityLinks(totalNode, totalShip, list, nodeItem.getDomain(), nodeItem.getNodeName(), nodeItem.getRange(), num);
        map.put("node",totalNode);
        map.put("relationship",totalShip);
        return map;
    }
    public boolean getDeepEntityLinks(ArrayList<Object> totalNode, ArrayList<Object> totalShip, List<HashMap<String, Object>> list,String domain, String nodeName, Integer range, Integer num){
        //判断递归次数
        if (!domain.equals("holdCompany") && !domain.equals("holdProduct")){
            if (num <= range) {
                //判断节点
                HashMap<String, Object> checkMap = new HashMap<>();
                checkMap.put(domain, nodeName);
                //判断当前节点是否已经被遍历过
                if (!list.contains(checkMap) ) {
                    //未遍历则添加当前节点
                    list.add(checkMap);
                    HashMap<String, Object> graphNodeAndShip = new HashMap<>();
                    ArrayList<HashMap<String, Object>> nodeList = new ArrayList<>();
                    ArrayList<HashMap<String, Object>> relList = new ArrayList<>();
                    //执行cql
                    /*String nodeSql = String.format("MATCH (n:`%s`) <-[r]->(m) where n.name='%s' return n,r,m", domain, nodeName);
                    HashMap<String, Object> graphNodeAndShip = Neo4jUtil.getDeepNodeAndShip(nodeSql);*/
                    String nodeSql1 = String.format("MATCH (n:`%s`) <-[r]->(m:`company`) where n.name='%s' return n,r,m", domain, nodeName);
                    HashMap<String, Object> graphNodeAndShip1 = Neo4jUtil.getDeepNodeAndShip(nodeSql1);
                    if (graphNodeAndShip1.size() > 0){
                        List<HashMap<String, Object>> node1 = (List<HashMap<String, Object>>)(graphNodeAndShip1.get("node"));
                        List<HashMap<String, Object>> rel1 = (List<HashMap<String, Object>>)(graphNodeAndShip1.get("relationship"));
                        if (node1.size() > 0){
                            nodeList.addAll(node1);
                        }
                        if (rel1.size() > 0){
                            relList.addAll(rel1);
                        }
                    }
                    String nodeSql2 = String.format("MATCH (n:`%s`) <-[r]->(m:`product`) where n.name='%s' return n,r,m", domain, nodeName);
                    HashMap<String, Object> graphNodeAndShip2 = Neo4jUtil.getDeepNodeAndShip(nodeSql2);
                    if (graphNodeAndShip2.size() > 0){
                        List<HashMap<String, Object>> node2 = (List<HashMap<String, Object>>)(graphNodeAndShip2.get("node"));
                        List<HashMap<String, Object>> rel2 = (List<HashMap<String, Object>>)(graphNodeAndShip2.get("relationship"));
                        if (node2.size() > 0){
                            nodeList.addAll(node2);
                        }
                        if (rel2.size() > 0){
                            List<HashMap<String, Object>> relationship = (List<HashMap<String, Object>>) graphNodeAndShip2.get("relationship");
                            relList.addAll(rel2);
                        }
                    }

                    String nodeSql3 = String.format("MATCH (n:`%s`) <-[r]->(m:`industy`) where n.name='%s' return n,r,m", domain, nodeName);
                    HashMap<String, Object> graphNodeAndShip3 = Neo4jUtil.getDeepNodeAndShip(nodeSql3);
                    if (graphNodeAndShip3.size() > 0){
                        List<HashMap<String, Object>> node3 = (List<HashMap<String, Object>>)(graphNodeAndShip3.get("node"));
                        List<HashMap<String, Object>> rel3 = (List<HashMap<String, Object>>)(graphNodeAndShip3.get("relationship"));
                        if (node3.size() > 0){
                            nodeList.addAll(node3);
                        }
                        if (rel3.size() > 0){
                            relList.addAll(rel3);
                        }
                    }

                    // 去重
                    ArrayList<HashMap<String, Object>> nodeMaps = new ArrayList<>(new HashSet<>(nodeList));
                    ArrayList<HashMap<String, Object>> relMaps = new ArrayList<>(new HashSet<>(relList));
                    graphNodeAndShip.put("node",nodeMaps);
                    graphNodeAndShip.put("relationship",relMaps);
                    List<HashMap<String, Object>> relationships = (List) graphNodeAndShip.get("relationship");
                    List<HashMap<String, Object>> nodes = (List) graphNodeAndShip.get("node");
                    if (nodes.size() > 0 && relationships.size() > 0) {
                        num++;
                        //将关系过滤后添加到总的map中
                        for (HashMap<String, Object> relationship : relationships) {
                            if (!totalShip.contains(relationship)) {
                                totalShip.add(relationship);
                            }
                        }
                        for (HashMap<String, Object> node : nodes) {
                            //将节点添加的总集合中
                            if (!totalNode.contains(node)) {
                                totalNode.add(node);
                            }
                            //查询尾节点
                            String label = (String) node.get("label");
                            HashMap<String, Object> properties = (HashMap<String, Object>) node.get("properties");
                            nodeName = (String) properties.get("name");
                            getDeepEntityLinks(totalNode, totalShip, list, label, nodeName, range, num);
                        }
                    }

                }
            }else{
                return false;
            }
            return true;
        }
        return true;
    }
    //获取公司主营业务
    String getCompanyBusiness(String nodeName){
        String currentNodeSql = String.format("MATCH (n:`%s`) where n.name='%s' return n", "company", nodeName);
        List<HashMap<String, Object>> currentNode = Neo4jUtil.getGraphNode(currentNodeSql);
        //当前公司的简介 计算相似度方法1
        String operation_business = "";
        if (currentNode.size() > 0){
            operation_business = (String) ((HashMap)currentNode.get(0).get("properties")).get("main_operation_business");
        }
        //System.out.println(operation_business);
        return operation_business;
    }
    List<String> getCompanyProduct(String nodeName){
        String nodeSql = String.format("MATCH (n:`%s`)-[r:`主营产品`]->(m) where n.name='%s' return m", "company", nodeName);
        // graphNode 公司的主营产品 计算相似度2
        List<String> graphNode = Neo4jUtil.getNodeName(nodeSql);
        ArrayList<String> graphNodeNew = new ArrayList<>(new HashSet<>(graphNode));
        //System.out.println(graphNodeNew);
        return graphNodeNew;
    }
    List<String> getHoldCompanyProduct(String nodeName){
        String nodeSql = String.format("MATCH (n:`%s`)-[r:`主营产品`]->(m) where n.name='%s' return m", "holdCompany", nodeName);
        // graphNode 公司的主营产品 计算相似度2
        List<String> graphNode = Neo4jUtil.getNodeName(nodeSql);
        ArrayList<String> graphNodeNew = new ArrayList<>(new HashSet<>(graphNode));
        //System.out.println(graphNodeNew);
        return graphNodeNew;
    }

    /**
     * 参数说明
     * @param list 竞争公司列表
     * @param companyProduct 公司产品集合 计算相似度方法1
     * @param companyBusiness 公司主营业务 计算相似度方法2
     * @param flag 1表示合作关系 0表示竞争关系
     * @param productList 竞争公司使用：计算原公司相似度方法3的控股公司产品集合
     * @return
     */
    ArrayList<HashMap<String, Object>> getSimilarity(ArrayList<HashMap<String, Object>> list,List<String> companyProduct,String companyBusiness,int flag, ArrayList<String> productList){
        //添加竞争公司的主营产品
        ArrayList<Double> doubleArrayList = new ArrayList<Double>();
        for (HashMap<String, Object> map : list) {

            //竞争公司的主营产品
            List<String> product = getCompanyProduct((String) ((HashMap) map.get("properties")).get("name"));
            map.put("product", product);
            //计算相似度1
            String competeBusiness = (String) ((HashMap)map.get("properties")).get("main_operation_business");
            double businessSimilarity = TextSimilarity.jaccardSimilarity(companyBusiness, competeBusiness);
            //double businessSimilarity = TextSimilarity.similar(companyBusiness, competeBusiness);
            //计算相似度2
            int count = 0;
            String currentCompeteProduct = "";
            String currentCompanyProduct = "";
            for (String s : (List<String>) map.get("product")) {
                currentCompeteProduct = currentCompeteProduct.concat(s);
            }
            for (String s1 : companyProduct) {
                currentCompanyProduct = currentCompanyProduct.concat(s1);
            }
            double productSimilarity = TextSimilarity.jaccardSimilarity(currentCompanyProduct, currentCompeteProduct);
            //double similarity = (businessSimilarity + productSimilarity) * 50;
            double similarity = 0.0;
            if (flag == 1){
                similarity = MathUtils.sigmoid(((businessSimilarity * 5  + productSimilarity *5) / 2));
                //System.out.println(similarity);
            }
            else {
                //每个竞争公司的控股公司
                List<String> holdCompany = getHoldCompany((String) ((HashMap) map.get("properties")).get("name"));

                //各个控股公司的产品集合
                ArrayList<String> holdProductList = new ArrayList<>();
                for (String company : holdCompany) {
                    holdProductList.addAll(getHoldCompanyProduct(company));
                }
                ArrayList<String> holdProduct = new ArrayList<>(new HashSet<>(holdProductList));
                //计算每个竞争公司与原公司的产品交集 作为相似度3
                //productList
                int number = 0;
                String companyProductString = "";
                String holdProductString = "";
                for (String s1 : productList) {
                    companyProductString = companyProductString.concat(s1);
                }
                for (String s : holdProduct) {
                    holdProductString = holdProductString.concat(s);

                }
//                for (String s : holdProduct) {
//                    for (String s1 : productList) {
//                        if(s.equals(s1)){
//                            number++;
//                            break;
//                        }
//                    }
//                }
                //double holdSimilarity = number / productList.size();
                double holdSimilarity = TextSimilarity.jaccardSimilarity(companyProductString, holdProductString);
                similarity = MathUtils.sigmoid((holdSimilarity * 5 + businessSimilarity * 4 + productSimilarity * 4) / 3);
                // System.out.println("similarity:" + similarity);
            }
            doubleArrayList.add(similarity);
            DecimalFormat df = new DecimalFormat("#.####");
            String metric = df.format(similarity);
            map.put("metric",metric);
        }
        for (HashMap<String, Object> map : list) {
            map.remove("product");
        }
        // 按照metric进行排序
        Collections.sort(list,new HashMapComparator("metric"));
        return list;
    }
    List<String> getHoldCompany(String nodeName){
        String currentNodeSql = String.format("MATCH (n:`%s`)-[r:`控股公司`]->(m) where n.name='%s' return m", "company", nodeName);
        List<String> holdNodeName = Neo4jUtil.getNodeName(currentNodeSql);
        ArrayList<String> nodeList = new ArrayList<>(new HashSet<>(holdNodeName));
        return nodeList;
    }
    @Override
    public HashMap<String, Object> getCompeteCompany(NodeItem nodeItem) {
        // 获取当前源节点自身信息
        String NodeSql = String.format("MATCH (n:`%s`) where n.name='%s' return n", "company", nodeItem.getNodeName());
        List<HashMap<String, Object>> selfNode = Neo4jUtil.getGraphNode(NodeSql);
        //返回封装数据
        HashMap<String, Object> competeMap = new HashMap<>();
        // 查询当前节点的信息。用于相似度计算1
        String companyBusiness = getCompanyBusiness(nodeItem.getNodeName());
        // 公司的主营产品 用于相似度计算2
        List<String> companyProduct = getCompanyProduct(nodeItem.getNodeName());
        // 当前公司的控股公司
        List<String> holdCompany = getHoldCompany(nodeItem.getNodeName());
        // 遍历控股公司合并主营产品
        ArrayList<String> holdProductOfCompany = new ArrayList<>();
        for (String company : holdCompany) {
            holdProductOfCompany.addAll(getHoldCompanyProduct(company));
        }
        // 当前公司控股产品集合
        ArrayList<String> holdProduct = new ArrayList<>(new HashSet<>(holdProductOfCompany));
        //得到当前公司的竞争公司
        ArrayList<HashMap<String, Object>> competeList = new ArrayList<>();
        for (String node : companyProduct) {
            String competeNodeSql = String.format("MATCH (n:`%s`)<-[r:`主营产品`]-(m) where n.name='%s' return m", "product", node);
            List<HashMap<String, Object>> competeNode = Neo4jUtil.getGraphNode(competeNodeSql);
            competeList.addAll(competeNode);
        }
        //竞争公司去重并去除当前节点
        ArrayList<HashMap<String, Object>> list = new ArrayList<>(new HashSet<>(competeList));
        //去重
        for (HashMap<String, Object> map : list) {
            if (nodeItem.getNodeId().equals((String) map.get("id"))) {
                list.remove(map);
                break;
            }
        }
        ArrayList<HashMap<String, Object>> competeCompany = getSimilarity(list, companyProduct, companyBusiness,0, holdProduct);
        // 计算切片的位置
        int splitIndex = competeCompany.size() * 3 / 10 + 1;
        // 切片并添加到两个新的ArrayList中
        // list1为图谱展示
        ArrayList<HashMap<String, Object>> list1 = new ArrayList<HashMap<String, Object>>(competeCompany.subList(0, splitIndex));
        // 为list1联系三元组关系
        ArrayList<HashMap<String,Object>> relationship = new ArrayList<>();
        int id = 1;
        for (HashMap<String, Object> map : list1) {

            HashMap<String, Object> map1 = new HashMap<>();
            HashMap<String, Object> properties = new HashMap<>();
            map1.put("source", nodeItem.getNodeId());
            map1.put("target", map.get("id"));
            properties.put("name", "竞争公司");
            properties.put("id",id++);
            map1.put("properties",properties);
            relationship.add(map1);
        }
        //添加源节点
        list1.addAll(selfNode);
        // list2为列表展示
        ArrayList<HashMap<String, Object>> list2 = new ArrayList<HashMap<String, Object>>(competeCompany.subList(splitIndex, competeCompany.size()));

        competeMap.put("kgCompeteCompany",list1);
        competeMap.put("relationship",relationship);
        competeMap.put("listCompeteCompany",list2);
        return competeMap;
    }

    @Override
    public HashMap<String, Object> getcooperateCompany(NodeItem nodeItem) {
        // 获取当前源节点自身信息
        String NodeSql = String.format("MATCH (n:`%s`) where n.name='%s' return n", "company", nodeItem.getNodeName());
        List<HashMap<String, Object>> selfNode = Neo4jUtil.getGraphNode(NodeSql);
        //返回封装数据
        HashMap<String, Object> competeMap = new HashMap<>();
        // 查询当前节点的信息。用于相似度计算1
        String companyBusiness = getCompanyBusiness(nodeItem.getNodeName());
        // 公司的主营产品 用于相似度计算2
        List<String> companyProduct = getCompanyProduct(nodeItem.getNodeName());

        HashMap<String, Object> cooperateMap = new HashMap<>();
        //得出当前公司主营产品
        String nodeSql = String.format("MATCH (n:`%s`)-[r:`主营产品`]->(m) where n.name='%s' return m", "company", nodeItem.getNodeName());
        List<String> graphNode = Neo4jUtil.getNodeName(nodeSql);
        HashSet<String> strings = new HashSet<>(graphNode);
        ArrayList<HashMap<String, Object>> upCooperateList = new ArrayList<>();
        for (String node : strings) {
            //得出主营产品上游产品节点
            //System.out.println(node);
            ArrayList<String> upNodes = new ArrayList<>();
            if("1".equals(nodeItem.getFlag())){
                //上游合作公司
                String cooperateNodeSql = String.format("MATCH (n:`%s`)-[r:`上游产品`]->(m) where n.name='%s' return m", "product", node);
                upNodes = (ArrayList<String>) Neo4jUtil.getNodeName(cooperateNodeSql);
            }else if("0".equals(nodeItem.getFlag())){
                //下游合作公司
                String cooperateNodeSql = String.format("MATCH (n:`%s`)<-[r:`上游产品`]-(m) where n.name='%s' return m", "product", node);
                upNodes = (ArrayList<String>) Neo4jUtil.getNodeName(cooperateNodeSql);
            }
            ArrayList<String> newList = new ArrayList<>();
            //遍历每个上游产品节点得到上游合作公司
            for (String upNode : upNodes) {
                String cooperateSql = String.format("MATCH (n:`%s`)<-[r:`主营产品`]-(m) where n.name='%s' return m", "product", upNode);
                List<HashMap<String, Object>> upCompany = Neo4jUtil.getGraphNode(cooperateSql);
                upCooperateList.addAll(upCompany);
            }
        }
        //合作公司产品去重
        ArrayList<HashMap<String, Object>> upCompany = new ArrayList<>(new HashSet<>(upCooperateList));
        for (HashMap<String, Object> map : upCompany) {
            if (map.get("id") == nodeItem.getNodeId()){
                upCompany.remove(map);
                break;
            }
        }
        ArrayList<HashMap<String, Object>> cooperateCompany = getSimilarity(upCompany, companyProduct, companyBusiness,1,null);
        // 计算切片的位置
        int splitIndex = cooperateCompany.size() * 3 / 10;
        if (splitIndex == 0){
            splitIndex++;
        }
        // 切片并添加到两个新的ArrayList中
        // list1为图谱展示
        ArrayList<HashMap<String, Object>> list1 = new ArrayList<HashMap<String, Object>>(cooperateCompany.subList(0, splitIndex));
        // 为list1联系三元组关系
        ArrayList<HashMap<String,Object>> relationship = new ArrayList<>();
        int id = 1;
        for (HashMap<String, Object> map : list1) {

            HashMap<String, Object> map1 = new HashMap<>();
            HashMap<String, Object> properties = new HashMap<>();
            map1.put("source", nodeItem.getNodeId());
            map1.put("target", map.get("id"));
            properties.put("name", "合作公司");
            properties.put("id",id++);
            map1.put("properties",properties);
            relationship.add(map1);
        }
        //
        list1.addAll(selfNode);
        // list2为列表展示
        ArrayList<HashMap<String, Object>> list2 = new ArrayList<HashMap<String, Object>>(cooperateCompany.subList(splitIndex, cooperateCompany.size()));
        cooperateMap.put("kgCooperateCompany",list1);
        cooperateMap.put("relationship",relationship);
        cooperateMap.put("listCooperateCompany",list2);
        //cooperateMap.put("cooperateCompany",cooperateCompany);
        //cooperateMap.put("downCompany",downCompany);
        return cooperateMap;

    }
    public ArrayList<HashMap<String, Object>> getKgCooperateCompany(String nodeName,String id,String flag){
        // 获取当前源节点自身信息
        String NodeSql = String.format("MATCH (n:`%s`) where n.name='%s' return n", "company", nodeName);
        List<HashMap<String, Object>> selfNode = Neo4jUtil.getGraphNode(NodeSql);
        //得出当前公司主营产品
        String nodeSql = String.format("MATCH (n:`%s`)-[r:`主营产品`]->(m) where n.name='%s' return m", "company", nodeName);
        List<String> graphNode = Neo4jUtil.getNodeName(nodeSql);
        HashSet<String> strings = new HashSet<>(graphNode);
        ArrayList<HashMap<String, Object>> upCooperateList = new ArrayList<>();
        for (String node : strings) {
            //得出主营产品上游产品节点
            //System.out.println(node);
            ArrayList<String> upNodes = new ArrayList<>();
            if("1".equals(flag)){
                //上游合作公司
                String cooperateNodeSql = String.format("MATCH (n:`%s`)-[r:`上游产品`]->(m) where n.name='%s' return m", "product", node);
                upNodes = (ArrayList<String>) Neo4jUtil.getNodeName(cooperateNodeSql);
            }else if("0".equals(flag)){
                //下游合作公司
                String cooperateNodeSql = String.format("MATCH (n:`%s`)<-[r:`上游产品`]-(m) where n.name='%s' return m", "product", node);
                upNodes = (ArrayList<String>) Neo4jUtil.getNodeName(cooperateNodeSql);
            }
            ArrayList<String> newList = new ArrayList<>();
            //遍历每个上游产品节点得到上游合作公司
            for (String upNode : upNodes) {
                String cooperateSql = String.format("MATCH (n:`%s`)<-[r:`主营产品`]-(m) where n.name='%s' return m", "product", upNode);
                List<HashMap<String, Object>> upCompany = Neo4jUtil.getGraphNode(cooperateSql);
                upCooperateList.addAll(upCompany);
            }
        }
        //合作公司产品去重
        ArrayList<HashMap<String, Object>> upCompany = new ArrayList<>(new HashSet<>(upCooperateList));
        for (HashMap<String, Object> map : upCompany) {
            if (map.get("id") == id){
                upCompany.remove(map);
                break;
            }
        }
        return upCompany;
    }
    public ArrayList<HashMap<String, Object>> getKgCompeteCompany(String nodeName,String id){
        // 获取当前源节点自身信息
        String NodeSql = String.format("MATCH (n:`%s`) where n.name='%s' return n", "company", nodeName);
        List<HashMap<String, Object>> selfNode = Neo4jUtil.getGraphNode(NodeSql);
        //返回封装数据
        HashMap<String, Object> competeMap = new HashMap<>();
        // 查询当前节点的信息。用于相似度计算1
        String companyBusiness = getCompanyBusiness(nodeName);
        // 公司的主营产品 用于相似度计算2
        List<String> companyProduct = getCompanyProduct(nodeName);
        // 当前公司的控股公司
        List<String> holdCompany = getHoldCompany(nodeName);
        // 遍历控股公司合并主营产品
        ArrayList<String> holdProductOfCompany = new ArrayList<>();
        for (String company : holdCompany) {
            holdProductOfCompany.addAll(getHoldCompanyProduct(company));
        }
        // 当前公司控股产品集合
        ArrayList<String> holdProduct = new ArrayList<>(new HashSet<>(holdProductOfCompany));
        //得到当前公司的竞争公司
        ArrayList<HashMap<String, Object>> competeList = new ArrayList<>();
        for (String node : companyProduct) {
            String competeNodeSql = String.format("MATCH (n:`%s`)<-[r:`主营产品`]-(m) where n.name='%s' return m", "product", node);
            List<HashMap<String, Object>> competeNode = Neo4jUtil.getGraphNode(competeNodeSql);
            competeList.addAll(competeNode);
        }
        //竞争公司去重并去除当前节点
        ArrayList<HashMap<String, Object>> list = new ArrayList<>(new HashSet<>(competeList));
        //去重
        for (HashMap<String, Object> map : list) {
            if (id.equals((String) map.get("id"))) {
                list.remove(map);
                break;
            }
        }
        return list;
    }
    @Override
    public HashMap<String, Object> getHiddenRelation(NodeItem nodeItem) {
        HashMap<String, Object> hashMap = new HashMap<>();
        ArrayList<HashMap<String, Object>> graphNode = new ArrayList<>();
        ArrayList<HashMap<String, Object>> graphRel = new ArrayList<>();
        HashMap<String, Object> graphNodeAndShip = Neo4jUtil.getGraphNodeAndShip(nodeItem.getCql());
        ArrayList<HashMap<String,Object>> node = (ArrayList<HashMap<String,Object>>)graphNodeAndShip.get("node");
        //System.out.println(node.size());
        ArrayList<HashMap<String,Object>> relationship = (ArrayList<HashMap<String,Object>>)graphNodeAndShip.get("relationship");
        //System.out.println(relationship.size());
        // 将当前所有公司加入到graphNode中
        //graphNode.addAll(node);
        int count = 1;
        for (HashMap<String, Object> map : node) {
            // 获取公司名称
            HashMap<String,Object> properties = (HashMap<String, Object>)map.get("properties");
            String name = (String) properties.get("name");
            String level = (String) properties.get("level");
            if (level !=null){
                switch (level){
                    case "1":
                        map.put("riskColor","#409EFF");
                        break;
                    case "2":
                        map.put("riskColor","#67C23A");
                        break;
                    case "3":
                        map.put("riskColor","#E6A23C");
                        break;
                    case "4":
                        map.put("riskColor","#F56C6C");
                        break;
                }
            }
            /*String id = (String) map.get("id");
            //获取该公司的竞争公司
            ArrayList<HashMap<String, Object>> kgCompeteCompany = getKgCompeteCompany(name, id);
            // 竞争公司风险等级添加
            for (HashMap<String, Object> competeCompany : kgCompeteCompany) {
                HashMap<String,Object> competeProperties = (HashMap<String, Object>)competeCompany.get("properties");
                String name1 = (String) competeProperties.get("name");
                String level1 = (String) competeProperties.get("level");
                switch (level1){
                    case "1":
                        competeCompany.put("riskColor","#00FF00");
                        break;
                    case "2":
                        competeCompany.put("riskColor","#FFFF00");
                        break;
                    case "3":
                        competeCompany.put("riskColor","#FF8C00");
                        break;
                    case "4":
                        competeCompany.put("riskColor","#FF0000");
                        break;
                }
            }
            // 竞争公司加入到graphNode
            graphNode.addAll(kgCompeteCompany);
            //建立竞争公司三元组
            ArrayList<HashMap<String,Object>> relationship1 = new ArrayList<>();
            for (HashMap<String, Object> company : kgCompeteCompany) {
                HashMap<String, Object> map1 = new HashMap<>();
                HashMap<String, Object> property = new HashMap<>();
                map1.put("source", id);
                map1.put("target", company.get("id"));
                property.put("name", "竞争公司");
                property.put("id",count++);
                map1.put("properties",property);
                relationship1.add(map1);
            }
            // 将竞争关系添加到所有的关系中
            graphRel.addAll(relationship1);
            //获取该公司的上游合作公司
            ArrayList<HashMap<String, Object>> kgUpCooperateCompany = getKgCooperateCompany(name, id, "1");
            // 上游合作公司风险等级添加
            for (HashMap<String, Object> upCompany : kgUpCooperateCompany) {
                HashMap<String,Object> upCompanyProperties = (HashMap<String, Object>)upCompany.get("properties");
                String name1 = (String) upCompanyProperties.get("name");
                String level1 = (String) upCompanyProperties.get("level");
                switch (level1){
                    case "1":
                        upCompany.put("riskColor","#00FF00");
                        break;
                    case "2":
                        upCompany.put("riskColor","#FFFF00");
                        break;
                    case "3":
                        upCompany.put("riskColor","#FF8C00");
                        break;
                    case "4":
                        upCompany.put("riskColor","#FF0000");
                        break;
                }
            }
            // 上游合作公司加入到graphNode
            graphNode.addAll(kgUpCooperateCompany);
            graphNode.addAll(kgCompeteCompany);
            ArrayList<HashMap<String,Object>> relationship2 = new ArrayList<>();
            for (HashMap<String, Object> company : kgUpCooperateCompany) {
                HashMap<String, Object> map1 = new HashMap<>();
                HashMap<String, Object> property = new HashMap<>();
                map1.put("source", id);
                map1.put("target", company.get("id"));
                property.put("name", "上游合作公司");
                property.put("id",count++);
                map1.put("properties",property);
                relationship2.add(map1);
            }
            // 将上游合作关系添加到所有的关系中
            graphRel.addAll(relationship2);
            //获取该公司的下游合作公司
            ArrayList<HashMap<String, Object>> kgDownCooperateCompany = getKgCooperateCompany(name, id, "0");
            // 下游合作公司风险等级添加
            for (HashMap<String, Object> downCompany : kgDownCooperateCompany) {
                HashMap<String,Object> downCompanyProperties = (HashMap<String, Object>)downCompany.get("properties");
                String name1 = (String) downCompanyProperties.get("name");
                String level1 = (String) downCompanyProperties.get("level");
                switch (level1){
                    case "1":
                        downCompany.put("riskColor","#00FF00");
                        break;
                    case "2":
                        downCompany.put("riskColor","#FFFF00");
                        break;
                    case "3":
                        downCompany.put("riskColor","#FF8C00");
                        break;
                    case "4":
                        downCompany.put("riskColor","#FF0000");
                        break;
                }
            }
            // 下游合作公司加入到graphNode
            graphNode.addAll(kgDownCooperateCompany);
            // 三元组
            ArrayList<HashMap<String,Object>> relationship3 = new ArrayList<>();
            for (HashMap<String, Object> company : kgDownCooperateCompany) {
                HashMap<String, Object> map1 = new HashMap<>();
                HashMap<String, Object> property = new HashMap<>();
                map1.put("source", id);
                map1.put("target", company.get("id"));
                property.put("name", "下游合作公司");
                property.put("id",count++);
                map1.put("properties",property);
                relationship3.add(map1);
            }
            // 将上游合作关系添加到所有的关系中
            graphRel.addAll(relationship3);*/

        }
        // 节点与关系去重
        ArrayList<HashMap<String, Object>> filterGraphNode = new ArrayList<>(new HashSet<>(node));
        ArrayList<HashMap<String, Object>> filterGraphRel = new ArrayList<>(new HashSet<>(relationship));

        //返回节点与关系
        hashMap.put("node",filterGraphNode);
        hashMap.put("relationship",filterGraphRel);
        return graphNodeAndShip;
    }

    @Override
    public HashMap<String, Object> getCompanyRisk(NodeItem nodeItem) {
        HashMap<String, Object> replaceCompany = new HashMap<>();
        // 获取当前源节点自身信息
        String NodeSql = String.format("MATCH (n:`%s`) where n.name='%s' return n", "company", nodeItem.getNodeName());
        List<HashMap<String, Object>> selfNode = Neo4jUtil.getGraphNode(NodeSql);

        HashMap<String, Object> map = selfNode.get(0);
        HashMap<String,Object> properties = (HashMap<String,Object>)map.get("properties");
        String risk = (String)properties.get("risk");
        // 高风险公司
        if ("4".equals((String) properties.get("level"))){
            //返回替换公司（竞争公司）
            ArrayList<HashMap<String, Object>> kgCompeteCompany = getKgCompeteCompany((String) properties.get("name"), (String) map.get("id"));
            replaceCompany.put("replaceCompany",kgCompeteCompany);
            replaceCompany.put("risk",risk);
            return replaceCompany;
        }
        //低风险公司，返回null
        replaceCompany.put("replaceCompany",null);
        replaceCompany.put("risk",risk);
        return replaceCompany;
    }

    @Override
    public HashMap<String, Object> getCompanyProduct(NodeItem nodeItem) {
        HashMap<String, Object> map = new HashMap<>();
        // 获取当前源节点自身信息
        String competeNodeSql = String.format("MATCH (n:`%s`)-[r:`主营产品`]->(m) where n.name='%s' return m", "company", nodeItem.getNodeName());
        List<HashMap<String, Object>> productNode = Neo4jUtil.getGraphNode(competeNodeSql);
        if (productNode.size() > 0){
            for (HashMap<String, Object> product : productNode) {
                HashMap<String,Object> properties = (HashMap<String,Object>)product.get("properties");
                String name = (String)properties.get("name");
                boolean flag = knowledgeGraphDao.isExistArticulationProduct(name);
                properties.put("articulationStatus",flag == true ? 1 : 0);
            }
        }
        Collections.sort(productNode, (h1, h2) -> (int)
                (int)((HashMap<String,Object>)h2.get("properties")).get("articulationStatus") - (int)((HashMap<String,Object>)h1.get("properties")).get("articulationStatus")
        );
        map.put("node",productNode);
        return map;
    }

    @Override
    public HashMap<String, Object> getArticulationProductGraph(String productName) {
        HashMap<String, Object> map = new HashMap<>();
        boolean flag = knowledgeGraphDao.isExistArticulationProduct(productName);
        if (flag){
            //是割点
            List<ArticulationProduct> articulationProductList = knowledgeGraphDao.getArticulationProduct(productName);
            if (articulationProductList.size() >1){
                articulationProductList = articulationProductList.subList(0,1);
            }
            ArticulationProduct articulationProduct = articulationProductList.get(0);
            //获取nodes集合
            String nodes = articulationProduct.getNodes();
            String[] nodeSplit = nodes.split(",");
            List<String> nodeList = Arrays.asList(nodeSplit);
            // 生成所有的nodeGraph集合
            ArrayList<HashMap<String, Object>> nodeGraph = new ArrayList<>();
            int nodeCount = 1;
            for (String node : nodeList) {
                HashMap<String, Object> nodeMap = new HashMap<>();
                HashMap<String, Object> properties = new HashMap<>();
                nodeMap.put("id",nodeCount++);
                nodeMap.put("label","product");
                properties.put("name",node);
                nodeMap.put("properties",properties);
                nodeGraph.add(nodeMap);
            }
            //System.out.println(nodeGraph);
            //获取before_edges节点集合
            String before_edge = articulationProduct.getBefore_edges();
            // rel的id全局计数
            int relCount = 1;
            // before局部链路图的节点id记录
            HashSet<Integer> beforeNodeIdSet = new HashSet<>();
            if (before_edge != null){
                String[] before_edges = before_edge.split(",");
                List<String> beforeEdgesList = Arrays.asList(before_edges);
                //System.out.println(beforeEdgesList);
                //封装rel与node节点
                ArrayList<HashMap<String, Object>> beforeGraphNode = new ArrayList<>();
                ArrayList<HashMap<String, Object>> beforeGraphRel = new ArrayList<>();
                for (String edge : beforeEdgesList) {
                    // 存放关系属性的properties
                    HashMap<String, Object> properties = new HashMap<>();
                    // 存放边与节点
                    HashMap<String, Object> rel = new HashMap<>();
                    HashMap<String, Object> node = new HashMap<>();
                    String[] edgeSplit = edge.split(":");
                    //定位源节点id
                    String sourceNodeName = edgeSplit[0];
                    for (HashMap<String, Object> nodeMap : nodeGraph) {
                        HashMap<String,Object> nameMap = (HashMap<String,Object>)nodeMap.get("properties");
                        String name = (String)nameMap.get("name");
                        if (sourceNodeName.equals(name)){
                            Integer id = (Integer)nodeMap.get("id");
                            //添加id
                            beforeNodeIdSet.add(id);
                            rel.put("source",id);
                            break;
                        }
                    }
                    // 定位目标节点id
                    String targetNodeName = edgeSplit[1];
                    for (HashMap<String, Object> nodeMap : nodeGraph) {
                        HashMap<String,Object> nameMap = (HashMap<String,Object>)nodeMap.get("properties");
                        String name = (String)nameMap.get("name");
                        if (targetNodeName.equals(name)){
                            Integer id = (Integer)nodeMap.get("id");
                            beforeNodeIdSet.add(id);
                            rel.put("target",id);
                            break;
                        }
                    }
                    //封装关系proeprties
                    properties.put("name","下游产品");
                    properties.put("id",relCount++);
                    rel.put("properties",properties);
                    beforeGraphRel.add(rel);
                    map.put("beforeRel",beforeGraphRel);
                }
            }else{
                map.put("beforeEdgesList",null);
            }
            //获取after_edges节点集合
            String after_edge = articulationProduct.getAfter_edges();
            // 断开后局部链路图中的节点id
            HashSet<Integer> afterNodeIdSet = new HashSet<>();
            if (after_edge != null){
                ArrayList<HashMap<String, Object>> afterGraphNode = new ArrayList<>();
                ArrayList<HashMap<String, Object>> afterGraphRel = new ArrayList<>();
                String[] after_edges = after_edge.split(",");
                List<String> afterEdgesList = Arrays.asList(after_edges);
                //System.out.println(afterEdgesList);
                for (String edge : afterEdgesList) {
                    // 存放关系属性的properties
                    HashMap<String, Object> properties = new HashMap<>();
                    // 存放边与节点
                    HashMap<String, Object> rel = new HashMap<>();
                    HashMap<String, Object> node = new HashMap<>();
                    String[] edgeSplit = edge.split(":");
                    //定位源节点id
                    String sourceNodeName = edgeSplit[0];
                    for (HashMap<String, Object> nodeMap : nodeGraph) {
                        HashMap<String,Object> nameMap = (HashMap<String,Object>)nodeMap.get("properties");
                        String name = (String)nameMap.get("name");
                        if (sourceNodeName.equals(name)){
                            Integer id = (Integer)nodeMap.get("id");
                            afterNodeIdSet.add(id);
                            rel.put("source",id);
                            break;
                        }
                    }
                    // 定位目标节点id
                    String targetNodeName = edgeSplit[1];
                    for (HashMap<String, Object> nodeMap : nodeGraph) {
                        HashMap<String,Object> nameMap = (HashMap<String,Object>)nodeMap.get("properties");
                        String name = (String)nameMap.get("name");
                        if (targetNodeName.equals(name)){
                            Integer id = (Integer)nodeMap.get("id");
                            afterNodeIdSet.add(id);
                            rel.put("target",id);
                            break;
                        }
                    }
                    //封装关系proeprties
                    properties.put("name","下游产品");
                    properties.put("id",relCount++);
                    rel.put("properties",properties);
                    afterGraphRel.add(rel);
                    map.put("afterRel",afterGraphRel);
                }

            }else{
                map.put("afterEdgesList",null);
            }
            //System.out.println("beforeNodeIdSet:" + beforeNodeIdSet);
            //System.out.println("afterNodeIdSet" + afterNodeIdSet);
            // 封装before与after的节点
            ArrayList<HashMap<String, Object>> beforeNode = new ArrayList<>();
            ArrayList<HashMap<String, Object>> afterNode = new ArrayList<>();
            for (Integer nodeId : beforeNodeIdSet) {
                for (HashMap<String, Object> node : nodeGraph) {
                    if (nodeId == (Integer)node.get("id")){
                        beforeNode.add(node);
                        break;
                    }
                }
            }
            for (Integer nodeId : afterNodeIdSet) {
                for (HashMap<String, Object> node : nodeGraph) {
                    if (nodeId == (Integer)node.get("id")){
                        afterNode.add(node);
                        break;
                    }
                }
            }
            map.put("beforeNode",beforeNode);
            map.put("afterNode",afterNode);
            //map.put("node",nodeGraph);
            return map;
        }
        return map;
    }

    @Override
    public HashMap<String, Object> getEtfLink(String number) {
        HashMap<String, Object> map = new HashMap<>();
        String NodeSql = String.format("MATCH (n:`%s`) return n limit %s", "etf", number);
        List<String> etfNodeList = Neo4jUtil.getNodeName(NodeSql);
        ArrayList<HashMap<String, Object>> nodeList = new ArrayList<>();
        ArrayList<HashMap<String, Object>> relationshipList = new ArrayList<>();
        for (String etfNode : etfNodeList) {
            String etfSql = String.format("MATCH (n:`%s`)-[r:`包含`]->(m) where n.name='%s' return n,r,m", "etf", etfNode);
            HashMap<String, Object> graphNodeAndShip = Neo4jUtil.getGraphNodeAndShip(etfSql);
            if (graphNodeAndShip.size() > 0){
                List<HashMap<String, Object>> node = (List<HashMap<String, Object>>)(graphNodeAndShip.get("node"));
                List<HashMap<String, Object>> rel = (List<HashMap<String, Object>>)(graphNodeAndShip.get("relationship"));
                if (node.size() > 0){
                    nodeList.addAll(node);
                }
                if (rel.size() > 0){
                    relationshipList.addAll(rel);
                }
            }
        }
        ArrayList<HashMap<String, Object>> node = new ArrayList<>(new HashSet<>(nodeList));
        ArrayList<HashMap<String, Object>> relationship = new ArrayList<>(new HashSet<>(relationshipList));
        map.put("node",node);
        map.put("relationship",relationship);
        return map;
    }


}